module SoftRenderer {
    export class Device {
        private canvas:HTMLCanvasElement;
        private context2d:CanvasRenderingContext2D;

        public width:number;
        public height:number;

        private backbufferImage:ImageData;
        private backbufferData;
        private depthBuffer:number[];

        constructor (canvas:HTMLCanvasElement) {
            this.canvas = canvas;
            this.width = canvas.width;
            this.height = canvas.height;
            this.context2d = canvas.getContext("2d");
            this.depthBuffer = new Array(this.width * this.height);
        }

        public clear () :void {
            this.context2d.clearRect(0, 0, this.width, this.height);
            this.backbufferImage = this.context2d.getImageData(0, 0, this.width, this.height);
            this.backbufferData = this.backbufferImage.data;
            for (var i = 0; i < this.depthBuffer.length; i++)
            {
                this.depthBuffer[i] = 10000000;
            }
        }

        public present () :void {
            this.context2d.putImageData(this.backbufferImage, 0, 0);
        }

        public putPixel (x:number, y:number, z:number, color:BABYLON.Color4, 
            depthTest:boolean = true, depthWrite:boolean = true) :void {
            // convert float to integer
            x = (x >> 0);
            y = (y >> 0);

            if (x < 0 || x >= this.width || 
                y < 0 || y >= this.height)
            {
                return;
            }

            var index:number = x + y * this.width;

            if (true === depthTest)
            {
                if (this.depthBuffer[index] < z)
                    return; // Discard
            }

            // As we have a 1-D Array for our back buffer
            // we need to know the equivalent cell index in 1-D based
            // on the 2D coordinates of the screen
            var index4:number = index * 4;

            // RGBA color space is used by the HTML5 canvas
            this.backbufferData[index4] = color.r * 255;
            this.backbufferData[index4 + 1] = color.g * 255;
            this.backbufferData[index4 + 2] = color.b * 255;
            this.backbufferData[index4 + 3] = color.a * 255;

            if (true === depthWrite)
            {
                this.depthBuffer[index] = z;
            }
        }
    }
}
